#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <math.h>
#include <linux/input.h>
#include <time.h>
#include <stdlib.h>

#define BLACK 0x00000000  // 黑色
#define RED 0x00ff0000    // 红色
#define GREEN 0x0000ff00  // 绿色
#define YELLOW 0x00ffff00 // 黄色
#define BLUE 0x000000ff   // 蓝色
#define PURPLE 0x00ff00ff // 紫色
#define CYAN 0x0000ffff   // 青色
#define WHITE 0x00ffffff  // 白色
#define GRAY 0x00808080   // 灰色
#define PINK 0x00ff8080   // 粉色
#define ORANGE 0x00ff8000 // 橙色

int color[] = {RED, GREEN, YELLOW, BLUE, PURPLE, CYAN, WHITE, GRAY, PINK, ORANGE};

int main()
{
    srand(time(NULL));

    int fd_touch = open("/dev/input/event0", O_RDWR);
    if (fd_touch < 0)
    {
        printf("open touch error %s\n", strerror(errno));
        return -1;
    }
    printf("open touch success\n");

    int fd_lcd = open("/dev/fb0", O_RDWR);
    if (fd_lcd < 0)
    {
        printf("open lcd error: %s\n", strerror(errno));
        return -1;
    }
    printf("open lcd success\n");

    int (*lcd_mmap)[800] = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd_lcd, 0);
    printf("mmap success\n");
    memset(lcd_mmap, 0, 800 * 480 * 4);
    int count = 0;

    // 读取触摸屏数据
    struct input_event buf;
    int x = -1, y = -1;
    int prev_x = -1, prev_y = -1; // 记录上一次的坐标
    int radius = 20;              // 圆的半径
    int color_index = 0;          // 随机颜色

    while (1)
    {
        if (count == 5)
        {
            color_index = (rand() + 1) % 10; // 随机颜色
            count = 0;
        }
        memset(&buf, 0, sizeof(buf));
        read(fd_touch, &buf, sizeof(buf));
        if (buf.type == EV_ABS)
        {
            if (buf.code == ABS_X)
            {
                x = buf.value * 800 / 1024;
            }
            else if (buf.code == ABS_Y)
            {
                y = buf.value * 480 / 600;
            }
        }
        if (buf.type == EV_SYN && x != -1 && y != -1)
        {

            // 绘制小圆边界     略微扩大边界，防止圆角部分无法删除干净
            int min_col = (prev_x > radius) ? prev_x - radius - 1 : 0;
            int max_col = (prev_x < 800 - radius) ? prev_x + radius + 1 : 800;
            int min_row = (prev_y > radius) ? prev_y - radius - 1 : 0;
            int max_row = (prev_y < 480 - radius) ? prev_y + radius + 1 : 480;

            printf("x = %d, y = %d\n", x, y);
            for (int row = min_row; row < max_row; row++)
            {
                for (int col = min_col; col < max_col; col++)
                {
                    int yx = col - prev_x;
                    int yy = row - prev_y;
                    if (pow(yx, 2) + pow(yy, 2) <= 20 * 20)
                    {
                        lcd_mmap[row][col] = 0x00000000;
                    }
                }
            }
            for (int row = min_row; row < max_row; row++)
            {
                for (int col = min_col; col < max_col; col++)
                {
                    int yx = col - x;
                    int yy = row - y;
                    if (pow(yx, 2) + pow(yy, 2) <= 20 * 20)
                    {
                        lcd_mmap[row][col] = color[color_index];
                    }
                }
            }
            prev_x = x;
            prev_y = y;
        }
        // 黑色屏幕底板开发板的 显示LCD分辨率 800*480 触摸屏的分辨率1024*600
        // 蓝色屏幕底板开发板的 显示LCD分辨率 800*480 触摸屏的分辨率800*480
        count++;
    }

    munmap(lcd_mmap, 800 * 480 * 4);

    close(fd_lcd);
    close(fd_touch);
    return 0;
}
/*
  Event types
  EV_ABS=3 // 绝对位移 屏幕触摸
        ABS_X=0  // X轴坐标
        ABS_Y=1  // Y轴坐标

  EV_KEY=1  // 按键事件
        code=330  // 触摸屏按下
        code=331  // 触摸屏松开

  EV_SYN=0  // 事件分割
 */
